/**********************************************************************************************************************
 * SplendidCRM is a Customer Relationship Management program created by SplendidCRM Software, Inc. 
 * Copyright (C) 2005-2011 SplendidCRM Software, Inc. All rights reserved.
 * 
 * This program is free software: you can redistribute it and/or modify it under the terms of the 
 * GNU Affero General Public License as published by the Free Software Foundation, either version 3 
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 * See the GNU Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License along with this program. 
 * If not, see <http://www.gnu.org/licenses/>. 
 * 
 * You can contact SplendidCRM Software, Inc. at email address support@splendidcrm.com. 
 * 
 * In accordance with Section 7(b) of the GNU Affero General Public License version 3, 
 * the Appropriate Legal Notices must display the following words on all interactive user interfaces: 
 * "Copyright (C) 2005-2011 SplendidCRM Software, Inc. All rights reserved."
 *********************************************************************************************************************/
using System;
using System.Data;
using System.Data.Common;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Diagnostics;
using SplendidCRM._controls;

namespace SplendidCRM.Meetings
{
	/// <summary>
	///		Summary description for EditView.
	/// </summary>
	public class EditView : SplendidControl
	{
		protected _controls.ModuleHeader   ctlModuleHeader  ;
		protected _controls.DynamicButtons ctlDynamicButtons;
		// 01/13/2010 Paul.  Add footer buttons. 
		protected _controls.DynamicButtons ctlFooterButtons ;

		protected Guid            gID                          ;
		protected HtmlTable       tblMain                      ;
		protected PlaceHolder     plcSubPanel                  ;

		protected InviteesView    ctlInviteesView              ;
		protected HiddenField     txtINVITEE_ID                ;

		protected Activities.SchedulingGrid ctlSchedulingGrid  ;

		protected void Page_Command(Object sender, CommandEventArgs e)
		{
			// 08/21/2005 Paul.  Redirect to parent if that is where the note was originated. 
			Guid   gPARENT_ID   = Sql.ToGuid(Request["PARENT_ID"]);
			string sMODULE      = String.Empty;
			string sPARENT_TYPE = String.Empty;
			string sPARENT_NAME = String.Empty;
			try
			{
				SqlProcs.spPARENT_Get(ref gPARENT_ID, ref sMODULE, ref sPARENT_TYPE, ref sPARENT_NAME);
			}
			catch(Exception ex)
			{
				SplendidError.SystemError(new StackTrace(true).GetFrame(0), ex);
				// The only possible error is a connection failure, so just ignore all errors. 
				gPARENT_ID = Guid.Empty;
			}
			if ( e.CommandName == "Save" )
			{
				try
				{
					this.ValidateEditViewFields(m_sMODULE + "." + LayoutEditView);
					// 11/10/2010 Paul.  Apply Business Rules. 
					this.ApplyEditViewValidationEventRules(m_sMODULE + "." + LayoutEditView);
					
					// 04/19/2010 Paul.  We now need to validate the sub panels as they can contain an inline NewRecord control. 
					if ( plcSubPanel.Visible )
					{
						foreach ( Control ctl in plcSubPanel.Controls )
						{
							InlineEditControl ctlSubPanel = ctl as InlineEditControl;
							if ( ctlSubPanel != null )
							{
								ctlSubPanel.ValidateEditViewFields();
							}
						}
					}
					if ( Page.IsValid )
					{
						// 09/09/2009 Paul.  Use the new function to get the table name. 
						string sTABLE_NAME = Crm.Modules.TableName(m_sMODULE);
						DataTable dtCustomFields = SplendidCache.FieldsMetaData_Validated(sTABLE_NAME);
						DbProviderFactory dbf = DbProviderFactories.GetFactory();
						using ( IDbConnection con = dbf.CreateConnection() )
						{
							con.Open();
							// 11/18/2007 Paul.  Use the current values for any that are not defined in the edit view. 
							DataRow   rowCurrent = null;
							DataTable dtCurrent  = new DataTable();
							if ( !Sql.IsEmptyGuid(gID) )
							{
								string sSQL ;
								sSQL = "select *              " + ControlChars.CrLf
								     + "  from vwMEETINGS_Edit" + ControlChars.CrLf;
								using ( IDbCommand cmd = con.CreateCommand() )
								{
									cmd.CommandText = sSQL;
									Security.Filter(cmd, m_sMODULE, "edit");
									Sql.AppendParameter(cmd, gID, "ID", false);
									using ( DbDataAdapter da = dbf.CreateDataAdapter() )
									{
										((IDbDataAdapter)da).SelectCommand = cmd;
										da.Fill(dtCurrent);
										if ( dtCurrent.Rows.Count > 0 )
										{
											rowCurrent = dtCurrent.Rows[0];
											// 12/09/2008 Paul.  Throw an exception if the record has been edited since the last load. 
											DateTime dtLAST_DATE_MODIFIED = Sql.ToDateTime(ViewState["LAST_DATE_MODIFIED"]);
											if ( Sql.ToBoolean(Application["CONFIG.enable_concurrency_check"]) && dtLAST_DATE_MODIFIED != DateTime.MinValue && Sql.ToDateTime(rowCurrent["DATE_MODIFIED"]) > dtLAST_DATE_MODIFIED )
												throw(new Exception(String.Format(L10n.Term(".ERR_CONCURRENCY_EXCEPTION"), dtLAST_DATE_MODIFIED)));
										}
										else
										{
											// 11/19/2007 Paul.  If the record is not found, clear the ID so that the record cannot be updated.
											// It is possible that the record exists, but that ACL rules prevent it from being selected. 
											gID = Guid.Empty;
										}
									}
								}
							}

							// 11/10/2010 Paul.  Apply Business Rules. 
							this.ApplyEditViewPreSaveEventRules(m_sMODULE + "." + LayoutEditView, rowCurrent);
							
							// 10/07/2009 Paul.  We need to create our own global transaction ID to support auditing and workflow on SQL Azure, PostgreSQL, Oracle, DB2 and MySQL. 
							using ( IDbTransaction trn = Sql.BeginTransaction(con) )
							{
								try
								{
									// 11/18/2007 Paul.  Use the current values for any that are not defined in the edit view. 
									// 12/29/2007 Paul.  TEAM_ID is now in the stored procedure. 
									SqlProcs.spMEETINGS_Update
										( ref gID
										, new DynamicControl(this, rowCurrent, "ASSIGNED_USER_ID").ID
										, new DynamicControl(this, rowCurrent, "NAME"            ).Text
										, new DynamicControl(this, rowCurrent, "LOCATION"        ).Text
										, new DynamicControl(this, rowCurrent, "DURATION_HOURS"  ).IntegerValue
										, new DynamicControl(this, rowCurrent, "DURATION_MINUTES").IntegerValue
										, new DynamicControl(this, rowCurrent, "DATE_START"      ).DateValue
										, new DynamicControl(this, rowCurrent, "STATUS"          ).SelectedValue
										// 02/04/2011 Paul.  We gave the PARENT_TYPE a unique name, but we need to update all EditViews and NewRecords. 
										, new DynamicControl(this, rowCurrent, "PARENT_ID_PARENT_TYPE").SelectedValue
										, new DynamicControl(this, rowCurrent, "PARENT_ID"       ).ID             // 01/31/2006 Paul.  Bug Fix, should be PARENT_ID, not APARENT_ID. 
										, new DynamicControl(this, rowCurrent, "SHOULD_REMIND"   ).Checked ? new DynamicControl(this, "REMINDER_TIME").IntegerValue : -1
										, new DynamicControl(this, rowCurrent, "DESCRIPTION"     ).Text
										, txtINVITEE_ID.Value
										, new DynamicControl(this, rowCurrent, "TEAM_ID"         ).ID
										, new DynamicControl(this, rowCurrent, "TEAM_SET_LIST"   ).Text
										, trn
										);
									SplendidDynamic.UpdateCustomFields(this, trn, gID, sTABLE_NAME, dtCustomFields);
									// 08/26/2010 Paul.  Add new record to tracker. 
									SqlProcs.spTRACKER_Update
										( Security.USER_ID
										, m_sMODULE
										, gID
										, new DynamicControl(this, rowCurrent, "NAME").Text
										, trn
										);
									if ( plcSubPanel.Visible )
									{
										// 01/27/2010 Paul.  The SubPanel can now have state that needs to be saved. 
										foreach ( Control ctl in plcSubPanel.Controls )
										{
											InlineEditControl ctlSubPanel = ctl as InlineEditControl;
											if ( ctlSubPanel != null )
											{
												ctlSubPanel.Save(gID, m_sMODULE, trn);
											}
										}
									}
									trn.Commit();
								}
								catch(Exception ex)
								{
									trn.Rollback();
									SplendidError.SystemError(new StackTrace(true).GetFrame(0), ex);
									ctlDynamicButtons.ErrorText = ex.Message;
									return;
								}
							}
						}
						// 11/10/2010 Paul.  Apply Business Rules. 
						this.ApplyEditViewPostSaveEventRules(m_sMODULE + "." + LayoutEditView);
						
						if ( !Sql.IsEmptyString(RulesRedirectURL) )
							Response.Redirect(RulesRedirectURL);
						else if ( !Sql.IsEmptyGuid(gPARENT_ID) )
							Response.Redirect("~/" + sMODULE + "/view.aspx?ID=" + gPARENT_ID.ToString());
						else
							Response.Redirect("view.aspx?ID=" + gID.ToString());
					}
				}
				catch(Exception ex)
				{
					SplendidError.SystemError(new StackTrace(true).GetFrame(0), ex);
					ctlDynamicButtons.ErrorText = ex.Message;
				}
			}
			else if ( e.CommandName == "Cancel" )
			{
				if ( !Sql.IsEmptyGuid(gPARENT_ID) )
					Response.Redirect("~/" + sMODULE + "/view.aspx?ID=" + gPARENT_ID.ToString());
				else if ( Sql.IsEmptyGuid(gID) )
					Response.Redirect("default.aspx");
				else
					Response.Redirect("view.aspx?ID=" + gID.ToString());
			}
			else if ( e.CommandName == "Invitees.Add" )
			{
				if ( txtINVITEE_ID.Value.Length > 0 )
					txtINVITEE_ID.Value += ",";
				txtINVITEE_ID.Value += e.CommandArgument;
				ctlInviteesView.INVITEES = txtINVITEE_ID.Value.Split(',');
				BindSchedule();
			}
			else if ( e.CommandName == "Invitees.Delete" )
			{
				string sDELETE_ID = e.CommandArgument.ToString().ToLower();
				string[] arrINVITEES = txtINVITEE_ID.Value.Split(',');
				StringBuilder sb = new StringBuilder();
				foreach(string sINVITEE_ID in arrINVITEES)
				{
					if ( sINVITEE_ID != sDELETE_ID )
					{
						if ( sb.Length > 0 )
							sb.Append(",");
						sb.Append(sINVITEE_ID);
					}
				}
				txtINVITEE_ID.Value = sb.ToString();
				ctlInviteesView.INVITEES = txtINVITEE_ID.Value.Split(',');
				BindSchedule();
			}
			else if ( e.CommandName == "Search" )
			{
				BindSchedule();
			}
		}

		protected void Date_Changed(object sender, System.EventArgs e)
		{
			BindSchedule();
		}

		private void BindSchedule()
		{
			DateTimePicker ctlDATE_START = FindControl("DATE_START" ) as DateTimePicker;
			if ( ctlDATE_START != null )
			{
				int nDURATION_HOURS   = new DynamicControl(this, "DURATION_HOURS"  ).IntegerValue;
				int nDURATION_MINUTES = new DynamicControl(this, "DURATION_MINUTES").IntegerValue;
				DateTime dtDATE_END = ctlDATE_START.Value.AddHours(nDURATION_HOURS).AddMinutes(nDURATION_MINUTES);
				// 07/09/2006 Paul.  The date values are sent to the scheduling grid in TimeZone time. 
				// The dates are converted to server time when the database is queried. 
				ctlSchedulingGrid.DATE_START = ctlDATE_START.Value;
				ctlSchedulingGrid.DATE_END   = dtDATE_END;
				ctlSchedulingGrid.INVITEES   = txtINVITEE_ID.Value.Split(',');
				ctlSchedulingGrid.BuildSchedule();
			}
		}

		private void Page_Load(object sender, System.EventArgs e)
		{
			SetPageTitle(L10n.Term(".moduleList." + m_sMODULE));
			// 06/04/2006 Paul.  Visibility is already controlled by the ASPX page, but it is probably a good idea to skip the load. 
			this.Visible = (SplendidCRM.Security.GetUserAccess(m_sMODULE, "edit") >= 0);
			if ( !this.Visible )
				return;

			try
			{
				gID = Sql.ToGuid(Request["ID"]);
				if ( !IsPostBack )
				{
					Guid gDuplicateID = Sql.ToGuid(Request["DuplicateID"]);
					if ( !Sql.IsEmptyGuid(gID) || !Sql.IsEmptyGuid(gDuplicateID) )
					{
						DbProviderFactory dbf = DbProviderFactories.GetFactory();
						using ( IDbConnection con = dbf.CreateConnection() )
						{
							con.Open();
							string sSQL ;
							sSQL = "select *              " + ControlChars.CrLf
							     + "  from vwMEETINGS_Edit" + ControlChars.CrLf;
							using ( IDbCommand cmd = con.CreateCommand() )
							{
								cmd.CommandText = sSQL;
								// 11/24/2006 Paul.  Use new Security.Filter() function to apply Team and ACL security rules.
								Security.Filter(cmd, m_sMODULE, "edit");
								if ( !Sql.IsEmptyGuid(gDuplicateID) )
								{
									Sql.AppendParameter(cmd, gDuplicateID, "ID", false);
									gID = Guid.Empty;
								}
								else
								{
									Sql.AppendParameter(cmd, gID, "ID", false);
								}

								if ( bDebug )
									RegisterClientScriptBlock("SQLCode", Sql.ClientScriptBlock(cmd));

								// 11/22/2010 Paul.  Convert data reader to data table for Rules Wizard. 
								using ( DbDataAdapter da = dbf.CreateDataAdapter() )
								{
									((IDbDataAdapter)da).SelectCommand = cmd;
									using ( DataTable dtCurrent = new DataTable() )
									{
										da.Fill(dtCurrent);
										if ( dtCurrent.Rows.Count > 0 )
										{
											DataRow rdr = dtCurrent.Rows[0];
											// 11/11/2010 Paul.  Apply Business Rules. 
											this.ApplyEditViewPreLoadEventRules(m_sMODULE + "." + LayoutEditView, rdr);
											
											ctlModuleHeader.Title = Sql.ToString(rdr["NAME"]);
											SetPageTitle(L10n.Term(".moduleList." + m_sMODULE) + " - " + ctlModuleHeader.Title);
											Utils.UpdateTracker(Page, m_sMODULE, gID, ctlModuleHeader.Title);
											ViewState["ctlModuleHeader.Title"] = ctlModuleHeader.Title;

											this.AppendEditViewFields(m_sMODULE + "." + LayoutEditView, tblMain, rdr);
											// 03/20/2008 Paul.  Dynamic buttons need to be recreated in order for events to fire. 
											ctlDynamicButtons.AppendButtons(m_sMODULE + "." + LayoutEditView, Sql.ToGuid(rdr["ASSIGNED_USER_ID"]), rdr);
											ctlFooterButtons .AppendButtons(m_sMODULE + "." + LayoutEditView, Sql.ToGuid(rdr["ASSIGNED_USER_ID"]), rdr);
											// 02/18/2009 Paul.  On load, the focus should be set to the NAME field. 
											TextBox txtNAME = this.FindControl("NAME") as TextBox;
											if ( txtNAME != null )
												txtNAME.Focus();

											DateTimePicker ctlDATE_START = FindControl("DATE_START") as DateTimePicker;
											if ( ctlDATE_START != null )
											{
												ctlDATE_START.Changed += new System.EventHandler(this.Date_Changed);
												ctlDATE_START.AutoPostBack = true;
											}
											// 08/02/2005 Paul.  Set status to Held when closing from Home page.
											// 06/21/2006 Paul.  Change parameter to Close so that the same parameter can be used for Calls, Meetings and Tasks. 
											try
											{
												if ( Sql.ToString(Request["Status"]) == "Close" )
													new DynamicControl(this, "STATUS").SelectedValue = "Held";
												else
													new DynamicControl(this, "STATUS").SelectedValue = Sql.ToString(rdr["STATUS"]);
											}
											catch(Exception ex)
											{
												SplendidError.SystemError(new StackTrace(true).GetFrame(0), ex);
											}

											int nDURATION_MINUTES = Sql.ToInteger(rdr["DURATION_MINUTES"]);
											// 02/17/2009 Paul.  Allow the duration to be something other than a 15 minute interval. 
											try
											{
												DropDownList ctlDURATION_MINUTES = FindControl("DURATION_MINUTES") as DropDownList;
												if ( ctlDURATION_MINUTES != null )
												{
													// 03/19/2009 Paul.  The selected value may already be set, so we must clear it otherwise an exception will be thrown. 
													// Cannot have multiple items selected in a DropDownList.
													ctlDURATION_MINUTES.ClearSelection();
													bool bFound = false;
													foreach(ListItem itm in ctlDURATION_MINUTES.Items)
													{
														if ( nDURATION_MINUTES == Sql.ToInteger(itm.Value) )
														{
															itm.Selected = true;
															bFound = true;
															break;
														}
													}
													// 02/17/2009 Paul.  If there is no match. then just add the custom value. 
													if ( !bFound )
													{
														ListItem itmCustom = new ListItem();
														// 04/23/2010 Paul.  Fix the presentation of the odd minutes. 
														itmCustom.Text  = String.Format(Sql.ToString(L10n.Term(".reminder_time_dom.", "300")).Replace("5", "{0}"), nDURATION_MINUTES);
														itmCustom.Value = nDURATION_MINUTES.ToString();
														ctlDURATION_MINUTES.Items.Add(itmCustom);
														itmCustom.Selected = true;
													}
												}
											}
											catch(Exception ex)
											{
												SplendidError.SystemError(new StackTrace(true).GetFrame(0), ex);
											}
											int nREMINDER_TIME = Sql.ToInteger(rdr["REMINDER_TIME"]);
											if ( nREMINDER_TIME >= 0 )
											{
												// 02/17/2009 Paul.  Allow the reminder to be something other than a 15 minute interval. 
												try
												{
													DropDownList ctlREMINDER_TIME = FindControl("REMINDER_TIME") as DropDownList;
													if ( ctlREMINDER_TIME != null )
													{
														// 03/19/2009 Paul.  The selected value may already be set, so we must clear it otherwise an exception will be thrown. 
														// Cannot have multiple items selected in a DropDownList.
														ctlREMINDER_TIME.ClearSelection();
														bool bFound = false;
														foreach(ListItem itm in ctlREMINDER_TIME.Items)
														{
															if ( nREMINDER_TIME == Sql.ToInteger(itm.Value) )
															{
																itm.Selected = true;
																bFound = true;
																break;
															}
														}
														// 02/17/2009 Paul.  If there is no match. then just add the custom value. 
														if ( !bFound && (nREMINDER_TIME / 60 > 0) )
														{
															ListItem itmCustom = new ListItem();
															// 04/23/2010 Paul.  Fix the presentation of the odd minutes. 
															itmCustom.Text  = String.Format(Sql.ToString(L10n.Term(".reminder_time_dom.", "300")).Replace("5", "{0}"), nREMINDER_TIME / 60);
															itmCustom.Value = nREMINDER_TIME.ToString();
															ctlREMINDER_TIME.Items.Add(itmCustom);
															itmCustom.Selected = true;
														}
													}
												}
												catch(Exception ex)
												{
													SplendidError.SystemError(new StackTrace(true).GetFrame(0), ex);
												}
												new DynamicControl(this, "SHOULD_REMIND").Checked = true;
											}
											else
											{
												// 03/04/2009 Paul.  If reminder is not specified, then hide the dropdown. 
												DropDownList ctlREMINDER_TIME = FindControl("REMINDER_TIME") as DropDownList;
												if ( ctlREMINDER_TIME != null )
												{
													ctlREMINDER_TIME.Style.Add("display", "none");
												}
											}
											// 12/09/2008 Paul.  Throw an exception if the record has been edited since the last load. 
											ViewState["LAST_DATE_MODIFIED"] = Sql.ToDateTime(rdr["DATE_MODIFIED"]);
											
											// 01/28/2010 Paul.  Use ViewState and Page.Items to be compatible with the DetailViews. 
											ViewState ["NAME"            ] = Sql.ToString(rdr["NAME"            ]);
											ViewState ["ASSIGNED_USER_ID"] = Sql.ToGuid  (rdr["ASSIGNED_USER_ID"]);
											Page.Items["NAME"            ] = ViewState ["NAME"            ];
											Page.Items["ASSIGNED_USER_ID"] = ViewState ["ASSIGNED_USER_ID"];
											// 11/10/2010 Paul.  Apply Business Rules. 
											this.ApplyEditViewPostLoadEventRules(m_sMODULE + "." + LayoutEditView, rdr);
										}
										else
										{
											// 11/25/2006 Paul.  If item is not visible, then don't allow save 
											// 03/20/2008 Paul.  Dynamic buttons need to be recreated in order for events to fire. 
											ctlDynamicButtons.AppendButtons(m_sMODULE + "." + LayoutEditView, Guid.Empty, null);
											ctlFooterButtons .AppendButtons(m_sMODULE + "." + LayoutEditView, Guid.Empty, null);
											ctlDynamicButtons.DisableAll();
											ctlFooterButtons .DisableAll();
											ctlDynamicButtons.ErrorText = L10n.Term("ACL.LBL_NO_ACCESS");
											// 01/27/2010 Paul.  Hide any subpanel data. 
											plcSubPanel.Visible = false;
										}
									}
								}
							}
							// 05/27/2007 Paul.  Fixed problem whereby vwCALLS_Invitees was used instead of the meetings version. 
							sSQL = "select INVITEE_ID                            " + ControlChars.CrLf
							     + "  from vwMEETINGS_Invitees                   " + ControlChars.CrLf
							     + " where MEETING_ID = @ID                      " + ControlChars.CrLf
							     + " order by INVITEE_TYPE desc, INVITEE_NAME asc" + ControlChars.CrLf;
							using ( IDbCommand cmd = con.CreateCommand() )
							{
								cmd.CommandText = sSQL;
								if ( !Sql.IsEmptyGuid(gDuplicateID) )
								{
									Sql.AddParameter(cmd, "@ID", gDuplicateID);
									gID = Guid.Empty;
								}
								else
								{
									Sql.AddParameter(cmd, "@ID", gID);
								}

								if ( bDebug )
									RegisterClientScriptBlock("vwMEETING_Invitees", Sql.ClientScriptBlock(cmd));

								using ( IDataReader rdr = cmd.ExecuteReader() )
								{
									StringBuilder sb = new StringBuilder();
									while ( rdr.Read() )
									{
										if ( sb.Length > 0 )
											sb.Append(",");
										sb.Append(Sql.ToString(rdr["INVITEE_ID"]).ToLower());
									}
									txtINVITEE_ID.Value = sb.ToString();
								}
							}
						}
					}
					else
					{
						this.AppendEditViewFields(m_sMODULE + "." + LayoutEditView, tblMain, null);
						// 03/20/2008 Paul.  Dynamic buttons need to be recreated in order for events to fire. 
						ctlDynamicButtons.AppendButtons(m_sMODULE + "." + LayoutEditView, Guid.Empty, null);
						ctlFooterButtons .AppendButtons(m_sMODULE + "." + LayoutEditView, Guid.Empty, null);
						// 02/18/2009 Paul.  On load, the focus should be set to the NAME field. 
						TextBox txtNAME = this.FindControl("NAME") as TextBox;
						if ( txtNAME != null )
							txtNAME.Focus();

						DateTimePicker ctlDATE_START = FindControl("DATE_START") as DateTimePicker;
						if ( ctlDATE_START != null )
						{
							ctlDATE_START.Changed += new System.EventHandler(this.Date_Changed);
							ctlDATE_START.AutoPostBack = true;
							// Default start date and time is now. 
							ctlDATE_START.Value = T10n.FromServerTime(DateTime.Now);
						}

						// Default value for duration is 00 minutes. 
						// 04/20/2011 Paul.  Zero minutes is just 0, not 00. 
						new DynamicControl(this, "DURATION_MINUTES").SelectedValue = "0";
						// Default to 1 hour. 
						new DynamicControl(this, "DURATION_HOURS"  ).Text = "1";
						// Default to remind. 
						new DynamicControl(this, "SHOULD_REMIND"   ).Checked = true;

						Guid gPARENT_ID = Sql.ToGuid(Request["PARENT_ID"]);
						if ( !Sql.IsEmptyGuid(gPARENT_ID) )
						{
							string sMODULE      = String.Empty;
							string sPARENT_TYPE = String.Empty;
							string sPARENT_NAME = String.Empty;
							SqlProcs.spPARENT_Get(ref gPARENT_ID, ref sMODULE, ref sPARENT_TYPE, ref sPARENT_NAME);
							if ( !Sql.IsEmptyGuid(gPARENT_ID) )
							{
								new DynamicControl(this, "PARENT_ID"  ).ID   = gPARENT_ID;
								new DynamicControl(this, "PARENT_NAME").Text = sPARENT_NAME;
								// 02/04/2011 Paul.  We gave the PARENT_TYPE a unique name, but we need to update all EditViews and NewRecords. 
								new DynamicControl(this, "PARENT_ID_PARENT_TYPE").SelectedValue = sPARENT_TYPE;
							}
						}
						// 11/10/2010 Paul.  Apply Business Rules. 
						this.ApplyEditViewNewEventRules(m_sMODULE + "." + LayoutEditView);
					}
					// Default to current user. 
					if ( txtINVITEE_ID.Value.Length == 0 )
						txtINVITEE_ID.Value = Security.USER_ID.ToString();
					BindSchedule();
				}
				else
				{
					// 12/02/2005 Paul.  When validation fails, the header title does not retain its value.  Update manually. 
					ctlModuleHeader.Title = Sql.ToString(ViewState["ctlModuleHeader.Title"]);
					SetPageTitle(L10n.Term(".moduleList." + m_sMODULE) + " - " + ctlModuleHeader.Title);
					// 01/28/2010 Paul.  We need to restore the page items on each postback. 
					Page.Items["NAME"            ] = ViewState ["NAME"            ];
					Page.Items["ASSIGNED_USER_ID"] = ViewState ["ASSIGNED_USER_ID"];
					// 11/09/2005 Paul.  Need to rebind early so that the Delete event will fire. 
					BindSchedule();
					ctlInviteesView.INVITEES = txtINVITEE_ID.Value.Split(',');
				}
			}
			catch(Exception ex)
			{
				SplendidError.SystemError(new StackTrace(true).GetFrame(0), ex);
				ctlDynamicButtons.ErrorText = ex.Message;
			}
		}

		#region Web Form Designer generated code
		override protected void OnInit(EventArgs e)
		{
			//
			// CODEGEN: This Meeting is required by the ASP.NET Web Form Designer.
			//
			InitializeComponent();
			base.OnInit(e);
		}
		
		/// <summary>
		///		Required method for Designer support - do not modify
		///		the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.Load += new System.EventHandler(this.Page_Load);
			ctlDynamicButtons.Command += new CommandEventHandler(Page_Command);
			ctlFooterButtons .Command += new CommandEventHandler(Page_Command);
			ctlInviteesView  .Command += new CommandEventHandler(this.Page_Command);
			ctlSchedulingGrid.Command += new CommandEventHandler(this.Page_Command);
			m_sMODULE = "Meetings";
			// 02/13/2007 Paul.  Meetings should highlight the Activities menu. 
			// 03/15/2011 Paul.  Change menu to use main module. 
			SetMenu(m_sMODULE);
			// 04/19/2010 Paul.  New approach to EditView Relationships will distinguish between New Record and Existing Record.
			bool bNewRecord = Sql.IsEmptyGuid(Request["ID"]);
			this.AppendEditViewRelationships(m_sMODULE + "." + LayoutEditView, plcSubPanel, bNewRecord);
			if ( IsPostBack )
			{
				// 12/02/2005 Paul.  Need to add the edit fields in order for events to fire. 
				this.AppendEditViewFields(m_sMODULE + "." + LayoutEditView, tblMain, null);
				// 03/20/2008 Paul.  Dynamic buttons need to be recreated in order for events to fire. 
				ctlDynamicButtons.AppendButtons(m_sMODULE + "." + LayoutEditView, Guid.Empty, null);
				ctlFooterButtons .AppendButtons(m_sMODULE + "." + LayoutEditView, Guid.Empty, null);
				
				DateTimePicker ctlDATE_START = FindControl("DATE_START") as DateTimePicker;
				if ( ctlDATE_START != null )
				{
					ctlDATE_START.Changed += new System.EventHandler(this.Date_Changed);
					ctlDATE_START.AutoPostBack = true;
				}
				// 11/10/2010 Paul.  Make sure to add the RulesValidator early in the pipeline. 
				Page.Validators.Add(new RulesValidator(this));
			}
		}
		#endregion
	}
}


